/**
 * Witontek.com.
 * Copyright (c) 2012-2018 All Rights Reserved.
 */
package test.map;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * 
 * @author Long
 * @version $Id: ObjectToMap.java, v 0.1 2018年1月17日 下午1:14:51  xiaolong.ma  Exp $
 */
public class ObjectToMap {
    public static void main(String[] args) throws Exception {
        TestObject o = new TestObject();
        o.setCity("beijing");
        o.setName("bj");
        o.setOrder("ASC");

        ObjectToMap objectToMap = new ObjectToMap();
        System.out.println("=========== Invoke objectToMapViaBeanInfo ===========");
        objectToMap.objectToMapViaBeanInfo(o);
        //        System.out.println("=========== Invoke objectToMapViaFields ===========");
        ////        objectToMap.objectToMapViaFields(o);
        //        System.out.println("=========== Invoke objectToMapViaApacheTools ===========");
        //        objectToMapViaApacheTools(o);
    }

    /** 
     * 通过Introspector 的方式复制属性值 
     * */
    private static void objectToMapViaBeanInfo(TestObject o) throws Exception {
        Map<String, Object> result = new HashMap<String, Object>();
        BeanInfo info = Introspector.getBeanInfo(o.getClass());
        for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
            Method reader = pd.getReadMethod();
            //内容为null的过滤掉  
            if (reader == null || reader.invoke(o) == null) {
                continue;
            }
            //默认继承Object类的属性，过滤掉  
            if (pd.getName().equalsIgnoreCase("class")) {
                continue;
            }
            result.put(pd.getName(), reader.invoke(o));
        }

        for (String key : result.keySet()) {
            System.out.println("Key:" + key + ";Value:" + result.get(key));
        }

    }

    /** 
     * 通过getDeclaredFields 的方式复制属性值 
     *  getDeclaredFields方式不会返回父类的属性 
     * */
    private static void objectToMapViaFields(TestObject o) throws IllegalAccessException {
        Map<String, Object> resMap = new HashMap<String, Object>();
        Field[] declaredFields = o.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            //过滤内容为空的  
            if (field.get(o) == null) {
                continue;
            }
            resMap.put(field.getName(), field.get(o));
        }
        printOut(resMap);
    }

    /** 
     * 通过Apache beanUtils的方式复制属性值 
     * 其内部实现方式同 方法1 
     * */
    private static void objectToMapViaApacheTools(TestObject o) {
        Map<String, Object> resMap = new org.apache.commons.beanutils.BeanMap(o);
        printOut(resMap);
    }

    /** 
     * 打印结果 
     * */
    private static void printOut(Map<String, Object> resMap) {
        for (String key : resMap.keySet()) {
            System.out.println("Key:" + key + ";Value:" + resMap.get(key));
        }
    }
}
